﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Ionic.Zip;
using System.IO;
using System.Xml;

namespace SpeedTestServerSetup
{
	public partial class Page5 : WizardPage
	{
        string sitePath = Path.Combine(Application.StartupPath, "InstallationFiles\\SpeedTestReports");

        public override event StateChangeEvent ReadyStateChanged;
        
        public Page5()
		{
			InitializeComponent();
		}

        public override void LeavePage(WizardEvents e)
		{
			//only validate if moving to the next page
			if (e.Direction != WizardDirection.Next) { return; }	

            e.Cancel = !UpdateXAP();
            if (e.Cancel)
            { e.ErrorMessage = "Unable to update the Silverlight xap file"; }
            else
            {
                if (rdoInstallHere.Checked && !String.IsNullOrEmpty(txtDirectory.Text))
                {
                    DirectoryInfo sourceDir = new DirectoryInfo(sitePath);
                    DirectoryInfo destDir = new DirectoryInfo(txtDirectory.Text);
                    CopyFiles(sourceDir, destDir);
                }
            }
		}

        private bool CopyFiles(DirectoryInfo sourceDir, DirectoryInfo destDir)
        {
            foreach (FileInfo fi in sourceDir.GetFiles())
            {
                File.Copy(fi.FullName, Path.Combine(destDir.FullName, fi.Name), true);
            }

            foreach (DirectoryInfo subDir in sourceDir.GetDirectories())
            {
                DirectoryInfo destSubDir = Directory.CreateDirectory(Path.Combine(destDir.FullName, subDir.Name));
                CopyFiles(subDir, destSubDir);
            }

            return true;
        }

        private bool UpdateXAP()    
        {

            string XAPPath = Path.Combine(sitePath, "ClientBin\\SpeedTestReports.xap");
            string configDir = Path.Combine(sitePath, "ClientBin");
            string configPath = Path.Combine(configDir, "ServiceReferences.ClientConfig");
            ZipFile zip = ZipFile.Read(XAPPath);
            ZipEntry xapentry = zip["ServiceReferences.ClientConfig"];
            xapentry.Extract(configDir);

            StreamReader reader = new StreamReader(configPath);
            string configXml = reader.ReadToEnd();
            reader.Close();

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(configXml);
            XmlNode node = doc.SelectSingleNode("configuration/system.serviceModel/client/endpoint");

            if (node != null)
            {
                XmlAttribute attr = node.Attributes["address"];
                attr.Value = "http://" + txtServerURI.Text + ":" + txtPort.Text + "/XAMLReports.asmx";
            }

            doc.Save(configPath);
            
            zip.UpdateItem(configPath, "");     //this file is located in the root directory in the zip
            zip.Save();

            File.Delete(configPath);

            return true;
        }

        private bool CreateInstallZip()
        {
            //create zip and prompt user for a save location

            SaveFileDialog sfd = new SaveFileDialog();
            sfd.CheckPathExists = true;
            sfd.Filter = "Zip Files|*.zip";

            DialogResult res = sfd.ShowDialog(this);

            if (res != DialogResult.Cancel)
            {
                ZipFile zip = new ZipFile();
                //put contents of this directory in the root of the zip file
                zip.AddDirectory(sitePath, ""); 
                zip.Save(sfd.FileName);
                
                MessageBox.Show(this, "Installation zip file created.");
            }

            return true;
        }

        public override void EnterPage(WizardEvents e)
		{
            if (e.Direction == WizardDirection.Previous && ReadyStateChanged != null) { ReadyStateChanged.Invoke(true); }
        }

        private void RequiredInput_TextChanged(object sender, EventArgs e)
        {
            if (ReadyStateChanged != null) { ReadyStateChanged.Invoke(IsPageReady()); }
        }

        private void RequiredInput_CheckedChanged(object sender, EventArgs e)
        {
            if (ReadyStateChanged != null) { ReadyStateChanged.Invoke(IsPageReady()); }
        }

        private void btnCreateZip_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(txtServerURI.Text) || String.IsNullOrEmpty(txtPort.Text))
            {
                MessageBox.Show("You must enter the Server URI and Port before creating the zip");
            }
            else
            {
                if (UpdateXAP())
                {
                    CreateInstallZip();
                }
            }
        }

        private void btnSelDirectory_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            DialogResult res = fbd.ShowDialog(this);

            if (res != DialogResult.Cancel)
            {
                txtDirectory.Text = fbd.SelectedPath;
            }
        }

        private bool IsPageReady()
        {
            if (String.IsNullOrEmpty( txtServerURI.Text)) { return false; }
            if (String.IsNullOrEmpty(txtPort.Text)) { return false; }

            //if we get here, the last two return true;
            if (rdoInstallHere.Checked && !String.IsNullOrEmpty(txtDirectory.Text)) { return true; }
            if (rdoInstallRemote.Checked) { return true; }

            return false;
        }

        private void txtPort_KeyPress(object sender, KeyPressEventArgs e)
        {
            int parsedNumber = 0;
            e.Handled = !Int32.TryParse(e.KeyChar.ToString(), out parsedNumber);
			if (e.KeyChar == (char)Keys.Delete || e.KeyChar == (char)Keys.Back) { e.Handled = false; }
        }

	}
}
